#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project ：pid_control_example 
@File ：deviation_correction1.py
@IDE  ：PyCharm 
@Author ：李涵彬
@Date ：2024/5/14 下午11:29 
"""
import socket
import time
from typing import Tuple

# 导入简单PID库
from simple_pid import PID


# 创建一个配置类来存储所有可配置的参数
class Config:
	def __init__(self):
		# 默认参数
		self.host = '127.0.0.1'  # 默认监听地址
		self.port = 65432  # 默认监听端口
		self.kp = 1.0  # 默认比例系数
		self.ki = 0.1  # 默认积分系数
		self.kd = 0.05  # 默认微分系数
		self.setpoint = 0.0  # 默认优化目标值


# 定义获取数据的函数，模拟通过 socket 获取数据
def get_data_from_socket(host: str, port: int) -> Tuple[float, float]:
	# 模拟通过 socket 获取数据的过程
	# 在实际情况下，你需要实现真实的数据获取逻辑
	actual_value = 0.5  # 模拟实际值
	setpoint = 0.0  # 模拟设定值
	return actual_value, setpoint


# 主程序
def main(config: Config):
	# 创建 PID 控制器对象并使用配置参数初始化
	pid = PID(config.kp, config.ki, config.kd, setpoint=config.setpoint)

	# 创建 socket 监听端口
	with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
		s.bind((config.host, config.port))
		s.listen()
		print(f"Listening on {config.host}:{config.port}...")
		conn, addr = s.accept()
		with conn:
			print(f"Connected by {addr}")
			while True:
				# 获取数据
				actual_value, setpoint = get_data_from_socket(config.host, config.port)

				# 更新 PID 控制器的设定值
				pid.setpoint = setpoint

				# 计算 PID 控制器的输出
				correction = pid(actual_value)

				# 在实际应用中，可以将 correction 发送给控制系统进行纠偏操作
				# 这里只是简单地打印出来
				print(f"Correction: {correction}")

				# 模拟间隔 200ms
				time.sleep(0.2)


if __name__ == "__main__":
	# 创建配置对象并设置参数
	config = Config()
	config.host = '127.0.0.1'  # 监听地址
	config.port = 65432  # 监听端口
	config.kp = 1.0  # 比例系数
	config.ki = 0.1  # 积分系数
	config.kd = 0.05  # 微分系数
	config.setpoint = 0.0  # 优化目标值

	# 执行主程序
	main(config)
